<!doctype html>
<!--
@license
Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<html>
<head>
  <meta charset="utf-8">
  <script src="../../node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js"></script>
  <script src="wct-browser-config.js"></script>
  <script src="../../node_modules/wct-browser-legacy/browser.js"></script>
  <script type="module" src="../../polymer-legacy.js"></script>
<body>

<script type="module">
import { beforeNextRender, afterNextRender } from '../../lib/utils/render-status.js';
import { LegacyElementMixin } from '../../lib/legacy/legacy-element-mixin.js';
class XFoo extends LegacyElementMixin(HTMLElement) {
  ready() {
    super.ready();
    sinon.spy(this, 'beforeNextRender');
    sinon.spy(this, 'stillBeforeNextRender');
    beforeNextRender(this, this.beforeNextRender,
      ['before']);
  }

  beforeNextRender() {
    beforeNextRender(this, this.stillBeforeNextRender,
      ['still-before']);
  }
  stillBeforeNextRender() {
    if (this.beforeDone) {
      this.beforeDone();
    }
  }
}
customElements.define('x-foo', XFoo);

class XBar extends LegacyElementMixin(HTMLElement) {
  ready() {
    super.ready();
    sinon.spy(this, 'afterNextRender');
    sinon.spy(this, 'afterAfterNextRender');
    afterNextRender(this, (a) => {
      this.afterNextRender(a);
    }, ['after']);
  }

  afterNextRender() {
    afterNextRender(this, (a) => {
      this.afterAfterNextRender(a);
    }, ['after-after']);
  }
  afterAfterNextRender() {
    if (this.afterDone) {
      this.afterDone();
    }
  }

}
customElements.define('x-bar', XBar);
</script>

<script type="module">
import { flush } from '../../lib/utils/render-status.js';

suite('render-status', function() {

  test('beforeNextRender', function(done) {
    let el = document.createElement('x-foo');
    document.body.appendChild(el);
    el.beforeDone = function() {
      assert.ok(el.beforeNextRender.withArgs('before').calledOnce);
      assert.ok(el.stillBeforeNextRender.withArgs('still-before').calledOnce);
      // break out of this raf so next test is not tainted.
      requestAnimationFrame(() => { done(); });
    };
  });

  test('afterNextRender', function(done) {
    let el = document.createElement('x-bar');
    let raf1 = sinon.spy();
    let raf2 = sinon.spy();
    requestAnimationFrame(() => {
      raf1();
      requestAnimationFrame(() => {
        raf2();
      });
    });
    el.afterDone = function() {
      assert.ok(el.afterNextRender.withArgs('after').calledOnce);
      assert.ok(el.afterNextRender.calledAfter(raf1));
      assert.ok(el.afterAfterNextRender.withArgs('after-after').calledOnce);
      assert.ok(el.afterAfterNextRender.calledAfter(raf2));
      // break out of this raf so next test is not tainted.
      requestAnimationFrame(() => { done(); });
    };
    document.body.appendChild(el);
  });

  test('flush', function() {
    let el1 = document.createElement('x-foo');
    let el2 = document.createElement('x-bar');
    document.body.appendChild(el1);
    document.body.appendChild(el2);
    flush();
    assert.ok(el1.beforeNextRender.withArgs('before').calledOnce);
    assert.ok(el1.stillBeforeNextRender.withArgs('still-before').calledOnce);
    assert.ok(el2.afterNextRender.withArgs('after').calledOnce);
    assert.ok(el2.afterAfterNextRender.withArgs('after-after').calledOnce);
  });

});
</script>

</body>
</html>
